home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 13258 < prev    next >
Encoding:
Text File  |  1996-08-05  |  5.4 KB  |  243 lines

  1. Path: taco.cc.ncsu.edu!news
  2. From: Scott Mebust <samebust@pop-in.ncsu.edu>
  3. Newsgroups: comp.lang.c++
  4. Subject: REPOST:  Template Class Nested Types
  5. Date: 23 Mar 1996 17:26:00 GMT
  6. Organization: North Carolina State University
  7. Message-ID: <4j1c78$1b5@taco.cc.ncsu.edu>
  8. NNTP-Posting-Host: s014h004.dialup.ncsu.edu
  9. Mime-Version: 1.0
  10. Content-Type: text/plain; charset=us-ascii
  11. Content-Transfer-Encoding: 7bit
  12. X-Mailer: Mozilla 1.22 (Windows; U; 16bit)
  13.  
  14. REPOST:  Sorry abuot the repost.  I'm not sure if this ever posted.
  15.  
  16. RE:  Template Class Nested Types:  Private member functions of the
  17.      enclosing class that take parameters of the enclosed class type.
  18.  
  19.      (Damn the terminology!  Fool speed ahead!)
  20.  
  21.  
  22. I've got a question concerning "Template Class Nested Types" (as Lippman
  23. refers to them in his C++ Primer, 2nd Edition).  Trying my hand at
  24. creating some generic dynamic data types (container classes) in C++ using
  25. templates, I've had some success.  (I know, I know, with STL around, why
  26. should one bother?  A:  To learn.)  I've implemented the standard Stack
  27. and Queue, and they were both easy to "templatize".  In my Queue class
  28. template, I declared a Node class within the private section of the Queue
  29. class declaration.  This worked out well.  I have since coded a binary
  30. tree class with a similarly nested Node class.  The non-templatized
  31. version of this class compiled without error and worked well.  However,
  32. when I attempted to convert the class to a class template, I ran into a
  33. problem.  In a nutshell, some of the private member functions of the
  34. Binary Tree class take a reference to a pointer to a Node as a parameter.
  35. The declarations of these member functions cause no problems but the
  36. definitions of the member functions, which are outside of the class
  37. declaration, cause the compilers (GNU 2.7.0(?) under Linux,
  38. Borland C++ 3.1) to choke.  They apparently don't recognize the Node
  39. class (that is, it appears to be out of scope).  But, if I move the body
  40. of these member functions into the Binary Tree class declaration (inline),
  41. the compilers happily accept the code.  I have tried qualifying the
  42. Node class with the Tree class name and template parameter list but this
  43. didn't help (i.e. tree<type>::node ).
  44.  
  45. Q:  What limitation am I running up against?  What is my misunderstanding?
  46.  
  47. I've included "complete" code snippets below that demonstrate the problem.
  48. The first snippet is a non-template integer binary tree that compiles fine.
  49. The second snippet is a templatized binary tree class that bombs a couple
  50. of lines into the tree::Insert2 member function definition.  The third
  51. snippet is a templatized version in which I've moved the body of the
  52. tree::Insert2 member function into the tree template class declaration
  53. (inline).  The third snippet also compiles fine.
  54.  
  55. Thanks in advance for any help with this problem.  I've referenced
  56. Stroustrup, Lippman, and a couple of other books concerning this but to
  57. no avail.
  58.  
  59. // SNIPPET 1 //
  60.  
  61. #include <stddef.h>
  62.  
  63. class inttree
  64. {
  65.   public:
  66.     inttree();
  67.     void Insert(const int &i);
  68.     //
  69.     // other member functions like Delete, etc.
  70.     //
  71.  
  72.   private:
  73.     class node
  74.     {
  75.       public:
  76.         int value_;
  77.         node *lchild_, *rchild_;
  78.     };
  79.  
  80.     void Insert2(const int &i, node* &np);
  81.     //
  82.     // other private member functions
  83.     //
  84.  
  85.     node *root_;
  86. };
  87.  
  88.  
  89.  
  90. inttree::inttree()
  91. {
  92.   root_=NULL;
  93. }
  94.  
  95.  
  96. void inttree::Insert(const int &i)
  97. {
  98.   Insert2(i, root_);
  99. }
  100.  
  101.  
  102. void inttree::Insert2(const int &i, node* &np)
  103. {
  104.   if (np==NULL)
  105.   {
  106.     np=new node;
  107.     // assert (np!=NULL);
  108.     np->lchild_=NULL;
  109.     np->rchild_=NULL;
  110.     np->value_=i;
  111.   }
  112.   else if (i<np->value_)
  113.     Insert2 (i,np->lchild_);
  114.   else if (i>np->value_)
  115.     Insert2 (i,np->rchild_);
  116. }
  117.  
  118. // END SNIPPET 1 //
  119.  
  120. // SNIPPET 2 //
  121.  
  122. #include <stddef.h>
  123.  
  124. template <class info>
  125. class tree
  126. {
  127.   public:
  128.     tree();
  129.     void Insert(const info &i);
  130.     //
  131.     // other member functions like Delete, etc.
  132.     //
  133.  
  134.   private:
  135.     class node
  136.     {
  137.       public:
  138.         info value_;
  139.         node *lchild_, *rchild_;
  140.     };
  141.  
  142.     void Insert2(const info &i, node* &np);
  143.     //
  144.     // other private member functions
  145.     //
  146.  
  147.     node *root_;
  148. };
  149.  
  150.  
  151. template <class info>
  152. tree<info>::tree()
  153. {
  154.   root_=NULL;
  155. }
  156.  
  157. template <class info>
  158. void tree<info>::Insert(const info &i)
  159. {
  160.   Insert2(i, root_);
  161. }
  162.  
  163. template <class info>
  164. void tree<info>::Insert2(const info &i, node* &np)
  165. {
  166.   if (np==NULL)
  167.   {
  168.     np=new node;
  169.     // assert (np!=NULL);
  170.     np->lchild_=NULL;
  171.     np->rchild_=NULL;
  172.     np->value_=i;
  173.   }
  174.   else if (i<np->value_)
  175.     Insert2 (i,np->lchild_);
  176.   else if (i>np->value_)
  177.     Insert2 (i,np->rchild_);
  178. }
  179.  
  180. // END SNIPPET 2 //
  181.  
  182. // SNIPPET 3 //
  183.  
  184. #include <stddef.h>
  185.  
  186. template <class info>
  187. class tree
  188. {
  189.   public:
  190.     tree();
  191.     void Insert(const info &i);
  192.     //
  193.     // other member functions like Delete, etc.
  194.     //
  195.  
  196.   private:
  197.     class node
  198.     {
  199.       public:
  200.         info value_;
  201.         node *lchild_, *rchild_;
  202.     };
  203.  
  204.     void Insert2(const info &i, node* &np)
  205.     {
  206.       if (np==NULL)
  207.       {
  208.         np=new node;
  209.         // assert (np!=NULL);
  210.         np->lchild_=NULL;
  211.         np->rchild_=NULL;
  212.         np->value_=i;
  213.       }
  214.       else if (i<np->value_)
  215.         Insert2 (i,np->lchild_);
  216.       else if (i>np->value_)
  217.         Insert2 (i,np->rchild_);
  218.     }
  219.     //
  220.     // other private member functions
  221.     //
  222.  
  223.     node *root_;
  224. };
  225.  
  226.  
  227. template <class info>
  228. tree<info>::tree()
  229. {
  230.   root_=NULL;
  231. }
  232.  
  233. template <class info>
  234. void tree<info>::Insert(const info &i)
  235. {
  236.   Insert2(i, root_);
  237. }
  238.  
  239. // END SNIPPET 3 //
  240.  
  241.  
  242.  
  243.